package com.solt.prism.dao.imp;

import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;

import com.solt.prism.core.conf.PrismConfiguration;
import com.solt.prism.core.utils.PrismConstants;


public class SqlConnectionPool {
	
	public static final String FILE_CONF = "conf/database.properties";
	
	private String strDriver;
	private String strDBCont;
	private DataSource dataSource;
	private static SqlConnectionPool pool = null;
	private static SqlConnectionPool sqlServerPool = null;

	private SqlConnectionPool (String url) {
		dataSource = setupDatasource(url);
	}
	
	public boolean isClose () {
		return false;
	}
	
	private SqlConnectionPool() {
		try {

			strDriver = "com.mysql.jdbc.Driver";
			Class.forName(strDriver).newInstance();
			Properties props = new Properties();
			Reader reader = new FileReader(new File(FILE_CONF));
			props.load(reader);
			String host = props.getProperty("dbHost","localhost");
			String db = props.getProperty("dbName", "webtin");
			String user = props.getProperty("dbUser", "root");
			String pass = props.getProperty("dbPass","andung");
			strDBCont = "jdbc:mysql://" + host + "/" + db + "?user=" + user
					+ "&password=" + pass
					+ "&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";

			dataSource = setupDatasource(strDBCont);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private DataSource setupDatasource(String strDB) {
		//
		// First, we'll need a ObjectPool that serves as the
		// actual pool of connections.
		//
		// We'll use a GenericObjectPool instance, although
		// any ObjectPool implementation will suffice.
		//
		ObjectPool connectionPool = new GenericObjectPool(null,80,GenericObjectPool.WHEN_EXHAUSTED_BLOCK,10000,10);
		
		//
		// Next, we'll create a ConnectionFactory that the
		// pool will use to create Connections.
		// We'll use the DriverManagerConnectionFactory,
		// using the connect string passed in the command line
		// arguments.
		//
		ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
				strDB, null);
		
		PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
				connectionFactory, connectionPool, null, null, false, true);

		//
		// Now we'll create the PoolableConnectionFactory, which wraps
		// the "real" Connections created by the ConnectionFactory with
		// the classes that implement the pooling functionality.
		//
	
		//
		// Finally, we create the PoolingDriver itself,
		// passing in the object pool we created.
		//
		return new PoolingDataSource(connectionPool);
	}

	public static synchronized Connection getConnection () throws SQLException {
		try {
			if (pool == null) {
				pool = new SqlConnectionPool(PrismConfiguration.getInstance().get(PrismConstants.SQL_LOGIN_URL));
			}
			return pool.dataSource.getConnection();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("reset connection pool !");
			pool = null;
			return getConnection();
		}
		
	}
	
	
	private static int trytime = 3;
	
	public static synchronized Connection getSqlServerConnection () {
		if (trytime > -1) {
			try {
				if (sqlServerPool == null ) {
					sqlServerPool = new SqlConnectionPool(PrismConfiguration.getInstance().get(PrismConstants.SQLSERVER_LOGIN_URL));
				}
				return sqlServerPool.dataSource.getConnection();
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("reset sqlserver connection pool !");
				sqlServerPool = null;
				--trytime;
				return getSqlServerConnection();
			}
			
		} else {
			System.exit(-1);
			return null;
		}
		
		
		
	}
	
	
	/**
	 * @param args
	 * @throws SQLException 
	 */
	public static void main(String[] args) throws SQLException {
	//	SqlConnectionPool.getConnection();
		SqlConnectionPool.getSqlServerConnection();
	}

}
